回想昨天的程式碼。
var Car = mixin( Vehicle, {
wheels: 4,
drive: function() {
vehicle.drive.call( this );
console.log( "Rooling on all " + this.wheels + " wheels!");
}
})
觀察這段 Vehicle.drive.call( this )
因為指定了父層 Vehicle,他不是相對多型的樣貌 inherits: drive()
。
這是明確的虛擬多型 ( explicit pseudopolymorphism )。
ES6 才有相對多型的機制。在這之前,必須明確的指定是使用Vehicle.drive(),並用上明確繫結。
明確的混合,比較複雜、難以閱讀。增加的成本遠多於好處。
盡可能避免使用明確的混合。
上面的方法,直接把 Vehicle 混入了 Car。
混合複製就是,先把 Vehicle 混進 空物件。
再將 Car 混進這個有 Vehicle 的物件。
不一樣的 mixin。
function mixinCopy( sourceObj, targetObj){
for( var key in sourceObj ) {
targetObj[key] = sourceObj[key];
}
return targerObj;
}
var Car = mixinCopy( Vehicle, {} )
mixinCopy( {
// 寫入任何你想放入 Car 的屬性。
}, Car )
JavaScript 函式無法真正被複製,這都是複製參考。
如果你修改了 ignition(),那 Vehicle 和 Car 都會被影響。
在不斷混入的情況下,你就可以做到多重繼承。
在往後的章節,有更多的方法可以達成,並避免麻煩。
function Vehicle() {
this.engines = 1;
}
Vehicle.prototype.ignition = function() {
console.log( "Turning on my engine." );
}
Vehicle.prototype.drive = function() {
this.ignition();
console.log( "Steering and moving forward!" );
}
// Vehicle 物件建置完成
function Car() {
var car = new Vehicle();
car.wheels = 4;
var vehDrive = car.drive;
car.drive = function() {
vehDrive.call( this );
console.log( "Rolling on all " + this.wheels + " wheels!");
};
return car;
}
var myCar = new Car();
myCar.drive();
// Turning on my engine.
// Steering and moving forward!
// Rolling on all 4 wheels!
單看 Car。
new Car()呼叫時,有幾件事情發生
But 他回傳了 car!Car 物件會被丟棄。
所以在呼叫 Car() 時,可以不用帶 new 喔!
var Something = {
cool: function() {
this.greeting = "Hello World";
this.count = this.count ? this.count : 1;
}
};
Something.cool();
Something.greeting; // "Hello World"
Something.count; // 1
var Another = {
cool: function() {
Something.cool.call( this )
}
}
Another.cool();
Another.greeting; // "Hello World"
Another.count; // 1
但不管怎麼樣,複雜的程式碼,能避免就避免。